﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Galaktika.BI.Silverlight.Controls.BallGame.ScoreService
{
    [DebuggerStepThrough]
    public class ScoresClient : ClientBase<IScores>, IScores
    {
        // Fields
        private static EndpointAddress defaultAddress = new EndpointAddress("http://localhost:3333/Bubbles/Service/Scores.svc");
        private static Binding defaultBinding = new BasicHttpBinding();
        private SendOrPostCallback onAddScoreCompletedDelegate;
        private ClientBase<IScores>.BeginOperationDelegate onBeginAddScoreDelegate;
        private ClientBase<IScores>.EndOperationDelegate onEndAddScoreDelegate;

        // Events
        public event EventHandler<AsyncCompletedEventArgs> AddScoreCompleted;

        // Methods
        public ScoresClient()
            : this(defaultBinding, defaultAddress)
        {
        }

        public ScoresClient(Binding binding, EndpointAddress remoteAddress)
            : base(binding, remoteAddress)
        {
        }

        public void AddScoreAsync(int width, int height, int colors, int score, int date, int time, int code, string name)
        {
            this.AddScoreAsync(width, height, colors, score, date, time, code, name, null);
        }

        public void AddScoreAsync(int width, int height, int colors, int score, int date, int time, int code, string name, object userState)
        {
            if (this.onBeginAddScoreDelegate == null)
            {
                this.onBeginAddScoreDelegate = new ClientBase<IScores>.BeginOperationDelegate(this.OnBeginAddScore);
            }
            if (this.onEndAddScoreDelegate == null)
            {
                this.onEndAddScoreDelegate = new ClientBase<IScores>.EndOperationDelegate(this.OnEndAddScore);
            }
            if (this.onAddScoreCompletedDelegate == null)
            {
                this.onAddScoreCompletedDelegate = new SendOrPostCallback(this.OnAddScoreCompleted);
            }
            base.InvokeAsync(this.onBeginAddScoreDelegate, new object[] { width, height, colors, score, date, time, code, name }, this.onEndAddScoreDelegate, this.onAddScoreCompletedDelegate, userState);
        }

        IAsyncResult IScores.BeginAddScore(int width, int height, int colors, int score, int date, int time, int code, string name, AsyncCallback callback, object asyncState)
        {
            return base.Channel.BeginAddScore(width, height, colors, score, date, time, code, name, callback, asyncState);
        }

        void IScores.EndAddScore(IAsyncResult result)
        {
            base.Channel.EndAddScore(result);
        }

        protected override IScores CreateChannel()
        {
            return new ScoresClientChannel(this);
        }

        private void OnAddScoreCompleted(object state)
        {
            if (this.AddScoreCompleted != null)
            {
                ClientBase<IScores>.InvokeAsyncCompletedEventArgs args = (ClientBase<IScores>.InvokeAsyncCompletedEventArgs)state;
                this.AddScoreCompleted(this, new AsyncCompletedEventArgs(args.Error, args.Cancelled, args.UserState));
            }
        }

        private IAsyncResult OnBeginAddScore(object[] inValues, AsyncCallback callback, object asyncState)
        {
            int width = (int)inValues[0];
            int height = (int)inValues[1];
            int colors = (int)inValues[2];
            int score = (int)inValues[3];
            int date = (int)inValues[4];
            int time = (int)inValues[5];
            int code = (int)inValues[6];
            string name = (string)inValues[7];
            return ((IScores)this).BeginAddScore(width, height, colors, score, date, time, code, name, callback, asyncState);
        }

        private object[] OnEndAddScore(IAsyncResult result)
        {
            ((IScores)this).EndAddScore(result);
            return null;
        }

        // Nested Types
        private class ScoresClientChannel : ClientBase<IScores>.ChannelBase<IScores>, IScores
        {
            // Methods
            public ScoresClientChannel(ClientBase<IScores> client)
                : base(client)
            {
            }

            public IAsyncResult BeginAddScore(int width, int height, int colors, int score, int date, int time, int code, string name, AsyncCallback callback, object asyncState)
            {
                object[] objArray = new object[] { width, height, colors, score, date, time, code, name };
                return base.BeginInvoke("AddScore", objArray, callback, asyncState);
            }

            public void EndAddScore(IAsyncResult result)
            {
                object[] objArray = new object[0];
                base.EndInvoke("AddScore", objArray, result);
            }
        }
    }


}
